<template>
  <div
    :class="{
      'fas-column-form': true,
    }"
    ref="fas_column_form"
    :style="
      !isLock && isAndroid ? 'margin:0 14px 0 0px;width:calc(100% - 14px)' : ''
    "
  >
    <grid-layout
      ref="portalGridLayout"
      :class="isLock ? 'fas_portal_layout' : 'fas-vue-grid fas_portal_layout'"
      :layout="layoutData"
      :col-num="rowsNum"
      :row-height="30"
      :is-draggable="!isLock"
      :is-resizable="!isLock"
      :useCssTransforms="true"
      :margin="[portalPadding * 1, portalPadding * 1]"
      :cols="{ lg: 24, md: 16, sm: 12, xs: 10, xxs: 4 }"
      :breakpoints="{ lg: 1919, md: 1199, sm: 991, xs: !isLock && isAndroid ? 753 : 767, xxs: 390 }"
      @layout-updated="handleLayoutListUpdated"
      :responsive="responsive"
      @breakpoint-changed="breakpointChangedEvent"
      :style="{ minHeight: divContainerMinHeight }"
      :verticalCompact="verticalCompact"
      :preventCollision="preventCollision"
    >
      <grid-item
        v-for="item in layoutData"
        :data-key="item.i"
        :x="item.x"
        :y="item.y"
        :w="item.w"
        :h="item.h"
        :i="item.i"
        :key="item.i"
        :id="item.customId || undefined"
        class="show-outline-1"
        :style="{
          'z-index': item.zIndex || 1,
          'background-color': portletBackgroundColor,
        }"
        :minW="item.minCellCount || 1"
      >
        <div
          class="item-content"
          :class="!isLock && ''"
          style="position: relative; height: 100%; overflow: hidden"
        >
          <div class="bg"></div>

          <template v-for="curElement in element.list">
            <div
              v-if="
                curElement.Code == item.i || curElement.InstanceCode == item.i
              "
            >
              <div
                class="header"
                v-show="
                  (curElement.Code == item.i && !isLock) ||
                  (curElement.Code == item.i && !isLock) ||
                  curElement.IsShowRefreshButton
                "
              >
                <div class="title"> </div>
                <div class="toolbar">
                  <div
                    v-if="curElement.Code == item.i && !isLock"
                    @click="showEditDialog(curElement)"
                    class="cd2cd2 portletOutSettting"
                  >
                    <i class="icon-t-edit-doc-fine"></i>
                  </div>
                  <div
                    v-if="curElement.IsShowRefreshButton"
                    @click="refreshPortal(curElement.Code)"
                    :class="
                      isLock
                        ? 'refresh_lock cd2cd2 portletOutSettting'
                        : 'cd2cd2 portletOutSettting'
                    "
                  >
                    <i class="fas dx-icon icon-t-refresh"></i>
                  </div>
                  <div
                    :title="Terms?.protal?.delete"
                    class="cd2cd2 portletOutSettting"
                    v-if="curElement.Code == item.i && !isLock"
                    style="right: 2px"
                    @click="removeItem(curElement.Code)"
                  >
                    <i class="icon-t-delete-outlined"></i>
                  </div>
                </div>
                <div class="toolbar_mobile">
                  <div
                    v-if="curElement.Code == item.i && !isLock"
                    @click="showEditDialog(curElement)"
                    class="cd2cd2 portletOutSettting"
                  >
                    <i class="fas dx-icon icon-t-pencil"></i>
                  </div>
                  <div
                    v-if="curElement.IsShowRefreshButton"
                    @click="refreshPortal(curElement.Code)"
                    :class="
                      isLock
                        ? 'refresh_lock cd2cd2 portletOutSettting'
                        : 'cd2cd2 portletOutSettting'
                    "
                  >
                    <i class="fas dx-icon icon-t-refresh"></i>
                  </div>
                  <div
                    :title="Terms?.protal?.delete"
                    class="cd2cd2 portletOutSettting"
                    v-if="curElement.Code == item.i && !isLock"
                    style="right: 2px"
                    @click="removeItem(curElement.Code)"
                  >
                    <i
                      class="fas dx-icon icon-t-minus-circle-fill"
                      style="color: red !important"
                    ></i>
                  </div>
                </div>
              </div>
              <!-- :title="curElement.Title" -->
              <component
                v-if="
                  visibleItems.includes(curElement.Code) &&
                  !curElement.LoadJsComponent
                "
                :is="`${(curElement.Ext1 || curElement.Name).toLowerCase()}`"
                :key="curElement.Code"
                
                v-bind="portalParamsInstance[item.i]?.VBind"
                :code = "portalParamsInstance[item.i]?.ins?.Ext1||portalParamsInstance[item.i]?.ins?.Name"
                :ref="curElement.Code"
                v-on="portalParamsInstance[item.i]?.VOn"
                @loaded="portalLoaded(item, curElement)"
              ></component>
              <t-inner-loading
                v-if="curElement.ShowLoading"
                :showing="curElement.ShowLoading"
                label="加载中"
                label-class="text-teal"
                label-style="font-size: 1.1em"
              >
                <t-spinner-ios color="img-content-background" size="xs" />
              </t-inner-loading>
            </div>
          </template>
        </div>
      </grid-item>
    </grid-layout>
  </div>
</template>
<style>
@media (max-width: 767px) {
  /* 这里放置当屏幕尺寸小于768px时的CSS规则 */
  .show-outline-1 .toolbar {
    display: none !important;
  }

  .show-outline-1 .toolbar_mobile {
    display: flex !important;
  }
}

.paramPopover {
  right: 2px;
  top: 25px;
  padding-top: 0 !important;
}

.fas_popper__arrow:after {
  top: 1px;
  margin-left: -6px;
  border-top-width: 0 !important;
  border-bottom-color: #fff !important;
}

.show-outline-1 .toolbar {
  position: absolute;
  cursor: pointer;
  pointer-events: auto;
  z-index: 10000;
  right: 0;
  display: flex;
  justify-content: end;
  gap: 10px;
  height: 16px;
  align-items: center;
  background: #f0f2f5;
  border-radius: 0px 2px 0px 8px;
  margin: 1px 1px 0px 0px;
  height: 16px;
  padding: 0 12px;
}

.show-outline-1 .toolbar_mobile {
  position: absolute;
  cursor: pointer;
  pointer-events: auto;
  z-index: 10000;
  right: 0;
  display: flex;
  justify-content: end;
  gap: 2px;
  align-items: center;

  margin: 8px 8px 0px 0px;
  display: none;
}

.show-outline-1 .toolbar_mobile > div {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}

.show-outline-1 .toolbar_mobile i {
  font-size: 14px;
  color: var(--t-color);
}

.show-outline-1 .toolbar {
  display: none;
}

.show-outline-1:hover .toolbar {
  display: flex;
}

.show-outline-1 .toolbar i {
  font-size: 10px;
  color: var(--t-color);
}

.show-outline-1 .refresh_lock {
  display: none;
}

.show-outline-1:hover .refresh_lock {
  display: block;
}
</style>
<style>
.remove {
  position: absolute;
  right: 2px;
  top: 0;
  cursor: pointer;
  pointer-events: auto;
  z-index: 9999;
}

/* .PanelDxPopup .dx-button-mode-text.dx-state-hover{
    background-color: --var('color-hover');
  } */
.fas-vue-grid::before {
  content: '';
  background-size: calc(var(--t-size) / var(--t-cols)) var(--t-computed-height) !important;
  background-image: linear-gradient(to right, lightgrey 1px, transparent 1px),
    linear-gradient(to bottom, lightgrey 1px, transparent 1px);
  height: var(--t-size) !important;
  width: var(--t-size) !important;
  position: absolute;
  background-repeat: repeat;
  margin: var(--t-portal-padding) !important;
}

.fas-vue-grid .show-outline-1 {
  outline: 1px dashed #409eff !important;
  user-select: none;
}

.fas-vue-grid .vue-grid-item > .vue-resizable-handle {
  z-index: inherit;
}

.fas-vue-grid .show-outline-2 {
  outline: 2px dashed yellow;
  user-select: none;
  cursor: move;
}
</style>
<script>
if (!window.localMessage) {
  window.localMessage = {};
}
import { loadPortal } from './utils';
// preparePortal
import { preparePortal } from './lib/loadPortal';
import FasValidate from './FasValidate';
import { MixinsFill } from './mixinsFill';
import { MixinsStyleClass } from './mixinsStyleClass';
import GooeyMenu from './FloatActionButton.vue';
import RtAddPortletHelper, {
  CheckInParamsIsBind,
} from './RtAddPortletHelper.vue';
import RtEditorPortletHelper from './RtAddPortletHelper.vue';
import ContextMenu from './FloatActionButton.vue';
import MutualHelper from './FloatActionButton.vue';
import { MixinsPortal } from './mixins_portal';
import fasGridItem from './lib/grid-layout/components/GridItem';
import fasGridLayout from './lib/grid-layout/components/GridLayout';
import { Terms } from './lib/Term';
import { MixinsEvent } from './mixinsEvent';
import TInnerLoading from 't/basic/inner-loading';
import TSpinnerIos from 't/basic/spinner/SpinnerIos';
// import Template from '../render/proxy/Template/Template.vue';

// SysDefault = 0,
//         /// <summary>
//         /// 客户定制
//         /// </summary>
//         CustomDefault = 1,
//         /// <summary>
//         /// 个人>客户定制>系统缺省
//         /// </summary>
//         Personal = 2,
const INSTANCE_TYPE = {
  0: Terms.portalType.default,
  1: Terms.portalType.system,
  2: Terms.portalType.person,
};

export default {
  name: 'FasGeneratePortal',
  mixins: [
    FasValidate.mixinValidate,
    MixinsFill,
    MixinsStyleClass,
    MixinsPortal,
    MixinsEvent,
  ],
  components: {
    GridLayout: fasGridLayout,
    GridItem: fasGridItem,
    GooeyMenu,
    RtAddPortletHelper,
    ContextMenu,
    MutualHelper,
    RtEditorPortletHelper,
    TInnerLoading,
    TSpinnerIos,
  },
  props: [
    'model',
    'rules',
    'remote',
    'blanks',
    'display',
    'edit',
    'remoteOption',
    'platform',
    'preview',
    'containerKey',
    'dataSourceValue',
    'eventFunction',
    'fasBindContext',
    'pageMetaData',
    'isDevEnv',
    'ucContainer',
    'InstanceCode',
    'PageID',
    'localvars',
    'proxyCurInstance',
    'divContainerMinHeight',
    'portalPadding',
    'isAutoRefresh',
    'refreshInterval',
    'portletBackgroundColor',
    'eventList',
    'enablePlan',
    'AdvanceQueryComponent',
    'verticalCompact',
    'preventCollision',
  ],
  data() {
    this.portletWidgetInstanceList = [];
    return {
      element: { options: { customEditEnable: true }, list: [] },
      isChangeType: false,
      loading: Funcs.GetTerms(
        'Schema.Controls.Protal.title.loading',
        '加载中...',
      ),
      seft: this,
      asyncComponent: null,
      Terms: Terms,
      layoutData: [],
      lastLayoutData: null,
      rawLayoutData: [],
      responsive: true,
      curInstanceID: null,
      portalInstanceList: [],
      layoutChanged: false,
      isLock: true,
      rowHeight: 30, //16
      colNum: 24,
      canFullScreen: false,
      fullScreen: false,
      dragEnabled: true,
      widget: this.element,
      dataModels: this.model,
      isFirst: true,
      curInstanceList: [],
      curInstance: {},
      isMaster: false,
      portalParamsInstance: {},
      outParams: [],
      inParams: [],
      notifyInparamsList: {},
      autoRefreshList: {},
      localVarsWatcher: {},
      rowsNum: 24,
      colKey: 'lg',
      visibleItems: [],
      currenctPortalInstance: '',
    };
  },
  created() {},
  mounted() {
    document.addEventListener('scroll', this.handleScroll, { passive: true });
    document.addEventListener('resize', this.handleScroll, { passive: true });
    document.addEventListener('wheel', this.handleScroll, { passive: true });
    // document.addEventListener('touchstart', function (e) {
    //   // 检查触摸点是否在屏幕边缘
    //   if (e.touches[0].clientX < 50 && e.touches[0].clientY > 50) {
    //     // 阻止默认行为
    //     e.preventDefault();
    //     return false
    //   }
    // }, { passive: false });
    // document.addEventListener('touchmove', this.handleScroll, { passive: true });
    this.rowsNum = sessionStorage.getItem('rowsNum') || 24;
    if (!sessionStorage.getItem('rowsNum')) {
      sessionStorage.setItem('rowsNum', 24);
    }
    document.body.style.setProperty(
      '--t-size',
      `calc(100% - ${this.portalPadding / 2}px)`,
    );
    document.body.style.setProperty('--t-cols', this.rowsNum);
    document.body.style.setProperty(
      '--t-portal-padding',
      `${this.portalPadding / 2}px`,
    );
    document.body.style.setProperty(
      '--t-computed-height',
      `${30 + this.portalPadding * 1 - 2}px`,
    );
    this.$nextTick(async () => {
      //启用方案管理不在主动构建门户实例
      if (this.enablePlan) {
        return;
      }
      preparePortal(this.PageID);
      await this.getLayoutInfo(this.proxyCurInstance);
      if (!this.curInstance.LayoutInfoResponsive) {
        this.curInstance.LayoutInfoResponsive = {
          lg: {
            LayOutInfo: JSON.stringify(this.layoutData),
            sm: { LayOutInfo: JSON.stringify(this.layoutData) },
            md: { LayOutInfo: JSON.stringify(this.layoutData) },
            xs: { LayOutInfo: JSON.stringify(this.layoutData) },
            xxs: { LayOutInfo: JSON.stringify(this.layoutData) },
          },
        };
      }
    });
    if (this.isAutoRefresh) {
      this.timer = window.setInterval(() => {
        for (let i in this.portalParamsInstance) {
          this.portalParamsInstance[i].refreshFn();
        }
      }, this.refreshInterval);
    }
  },
  beforeDestroy() {
    for (let i in this.autoRefreshList) {
      if (this.autoRefreshList[i]) {
        window.clearInterval(this.autoRefreshList[i]);
        this.autoRefreshList[i] = null;
      }
    }
    if (this.timer) {
      window.clearInterval(this.timer);
      this.timer = null;
    }
    document.removeEventListener('scroll', this.handleScroll);
    document.removeEventListener('resize', this.handleScroll);
    document.removeEventListener('wheel', this.handleScroll);
    // document.removeEventListener('touchmove', this.handleScroll);
  },
  computed: {
    isAndroid() {
      var ua = navigator.userAgent;
      return /android/i.test(ua)&&this.$q.screen.xs&&this.$q.platform.is.mobile;
    },
    InstanceCode() {
      return this.InstanceCode;
    },

    // ...MakePublicProp(["InstanceCode", "ReadOnly", "Visible"]),
    Visible: {
      get() {
        return this.element.options.visible;
      },
      set(val) {
        this.element.options.visible = val;
      },
    },
    computedVisible() {
      return true;
    },
    computedStyle() {
      let style = {};
      if (this.computedHeight != null) {
        style.height = `${this.computedHeight}`.replace('px', '') + 'px';
      }
      return style;
    },
    fasWidgetList() {
      let list = _.flatten(_.map(this.element.columns, 'list'));
      return list;
    },
    ColumnForm: {
      get() {
        return this.element.options.columnForm;
      },
      set(val) {
        this.element.options.columnForm = val;
      },
    },
    portalSelectList() {
      return this.curInstanceList.map(item => {
        return {
          ID: item.ID,
          Name: INSTANCE_TYPE[item.InstanceType],
          Type: item.InstanceType,
        };
      });
    },
    canChange() {
      return false;
      // (
      //   false//JSON.stringify(this.lastLayoutData) == JSON.stringify(this.layoutData)
      // );
    },
    computedOutParams() {
      let res = [];
      for (let i in this.portalParamsInstance) {
        if (this.portalParamsInstance[i].outParams) {
          this.portalParamsInstance[i].detail.outParams.forEach(j => {
            res.push({
              instanceCode: i,
              label: j.Name,
              value: `_generateCode_outParams_${i}&&${j.Code}`,
            });
          });
        }
      }
      return res;
    },
    computedInparams() {
      let res = [];
      for (let i in this.portalParamsInstance) {
        if (this.portalParamsInstance[i].detail.inParams) {
          this.portalParamsInstance[i].detail.inParams.forEach(j => {
            res.push({
              instanceCode: i,
              label: j.Name,
              bind: {
                modelValue: this.portalParamsInstance[i].inParams[j.Code],
              },
              on: {
                'update:modelValue': e => {
                  this.updateInparams(i, j.Code, e);
                },
              },

              bindCode: j.Code,
            });
          });
        }
      }
      return res;
    },
  },
  methods: {
    emitChange() {
      if (this.isChanging) return;
      this.$emit('change');
    },
    handleScroll(event,nocheck) {
      if (!window.PortletsCompDependency) return [];
      const container = this.$refs.fas_column_form;
      let promiseList = [];
      this.element.list.forEach(item => {
        const element = document.querySelector(
          `.cssTransforms.show-outline-1[data-key="${item.Code}"]`,
        );
        if (!element || !container || item.LoadJsComponent) return;

        const bounds = element.getBoundingClientRect();
        const bounds_container = container.getBoundingClientRect();
        //窗口可是高度

        const isVisible =
          bounds.top < container.clientHeight + bounds_container.top &&
          bounds.bottom > 0 &&
          bounds.top < window.innerHeight;
        if (
          (isVisible &&
          !this.visibleItems.includes(item.Code) &&
          !item.LoadJsComponent)||nocheck
        ) {
          // 当组件进入可视区域且尚未加载时，将其加入visibleItems数组
          this.visibleItems.push(item.Code);
          let code = item.Ext1 || item.Name;
          item.Ext1 = '';

          item.LoadJsComponent = true;
          let portalList = [];
          if (this.element.options.layout.some(items => items.i == item.Code)) {
            let targetOptions = this.element.options.layout.find(
              items => items.i == item.Code,
            );
            portalList = targetOptions.PortletRelatedComponents
              ? targetOptions.PortletRelatedComponents.split(',')
              : [];
          }
          if (window.PortletsCompDependency[item.PortletMetadataID]) {
            portalList = _.cloneDeep(
              window.PortletsCompDependency[item.PortletMetadataID],
            );
          }
          item.ShowLoading = true;
          let load = new Promise(resolve => {
            loadPortal(item.Ext2, code, portalList).then(res => {
              item.Ext1 = code;
              item.LoadJsComponent = false;
              resolve(1);
              // setTimeout(() => {
              //   item.ShowLoading=false
              // }, 1500);
            }).catch(()=>{
              resolve(1);
            })
          });
          promiseList.push(load);

          // 这里可以添加加载图片的逻辑，比如使用Vue的v-lazy指令
        }
        Funcs.HideLoading();

        event && event.stopPropagation();
        return false;
      });
      return promiseList
    },
    refreshPortal(instanceCode) {
      this.$refs[instanceCode] &&
        this.$refs[instanceCode][0] &&
        this.$refs[instanceCode][0].refresh &&
        this.$refs[instanceCode][0].refresh();
    },
    /**
     * i: instanceCode
     * code: paramCode
     * e:paramValue
     */
    updateInparams(i, code, e) {
      //1 更新inparams
      // this.portalParamsInstance[i].inParams[code] = e;
      //2.更新原始数据
      this.portalParamsInstance[i].detail.inParams.forEach(item => {
        if (item.Code == code) {
          item.ParamValue = e;
          if (
            [
              'MetricsConfig',
              'StaticMetricsFilters',
              'MetricsFilters',
            ].includes(code) &&
            typeof item.ParamValue != 'string'
          ) {
            try {
              item.ParamValue = JSON.stringify(e);
            } catch (error) {}
            // this.portalParamsInstance[i].VBind[code] = e;
          }
        }
      });
      if (e && e.indexOf && e.indexOf('_generateCode_outParams_') != -1) {
        //3.更新v-bind劫持v-bind
        let outParamsList =
          e && e.replace ? e.replace(/_generateCode_outParams_/gi, '') : '';
        outParamsList = outParamsList.split('&&');
        let outParamsInstance = outParamsList[0];
        let outParamsCode = outParamsList[1];
        if (!this.notifyInparamsList[outParamsInstance]) {
          this.notifyInparamsList[outParamsInstance] = [];
        }
        //注册订阅
        this.notifyInparamsList[outParamsInstance].push({
          code: code,
          outParamsCode: outParamsCode,
          fn: e => {
            this.portalParamsInstance[i].VBind[code] = e;
          },
        });
        if (
          this.portalParamsInstance[i].VBind[code] ==
          this.outParams[outParamsInstance][outParamsCode]
        )
          return;
        this.portalParamsInstance[i].VBind[code] =
          this.outParams[outParamsInstance][outParamsCode];
        this.emitChange();
      } else if (e && e.indexOf && e.indexOf('LocalVars.') == 0) {
        if (this.portalParamsInstance[i].VBind[code] == _.get(window, e))
          return;
        //更新 vBind
        this.portalParamsInstance[i].VBind[code] = _.get(window, e);
        this.emitChange();
      } else {
        if (
          ['MetricsConfig', 'StaticMetricsFilters', 'MetricsFilters'].includes(
            code,
          )
        ) {
          try {
            e = eval(e);
          } catch (error) {
            try {
              e = JSON.parse(e);
            } catch (error) {}
          }
        }
        if (this.portalParamsInstance[i].VBind[code] == e) return;
        this.portalParamsInstance[i].VBind[code] = e;

        this.emitChange();
      }
    },
    backup() {
      this.isChangeType = true;

      this.getLayoutInfo(this.curInstance, this.currenctPortalInstance).then(
        res => {
          this.layoutChanged = false;
          this.isLock = true;
          setTimeout(() => {
            this.$nextTick(() => {
              this.isChangeType = false;
              this.element.list.forEach(item => {
                item.ShowLoading = false;
              });
            });
          }, 200);
        },
      );
    },
    Publish(param) {
      let publicParams = LocalVars['PublicParams'];
      if (!publicParams) {
        publicParams = {};
        this.$set(LocalVars, 'PublicParams', publicParams);
      }

      _.each(param, (pubParamVal, pubParamCode) => {
        this.$set(publicParams, pubParamCode, pubParamVal);
      });

      _.each(this.portletWidgetInstanceList, ins => {
        let changeParamsArgs = {};
        _.each(param, (pubParamVal, pubParamCode) => {
          _.each(
            ins.commParamMapping,
            (portaletParam, portaletPubParamCode) => {
              if (
                _.has(ins, portaletParam.Code) &&
                portaletPubParamCode == pubParamCode
              ) {
                ins[portaletParam.Code] = pubParamVal;
                changeParamsArgs[portaletParam.Code] = pubParamVal;
              }
            },
          );
        });
        if (false === _.isEmpty(changeParamsArgs)) {
          ins.publicParamsChanged(changeParamsArgs);
        }
      });
    },
    syncPublish2Portlet(ins, publicParams) {
      let changeParamsArgs = {};
      publicParams = publicParams || LocalVars['PublicParams'] || {};
      if (publicParams) {
        _.each(ins.commParamMapping, (portaletParam, portaletPubParamCode) => {
          if (_.has(ins, portaletParam.Code)) {
            if (portaletParam.PublicParam && portaletParam.PublicParam.Code) {
              let pubParamValue = publicParams[portaletPubParamCode];
              if (pubParamValue !== undefined) {
                ins[portaletParam.Code] = pubParamValue;
                changeParamsArgs[portaletParam.Code] = pubParamValue;
              }
            }
          }
        });
      }
      return changeParamsArgs;
    },
    registerPortlet(portletIns) {
      if (false === _.includes(this.portletWidgetInstanceList, portletIns)) {
        this.portletWidgetInstanceList.push(portletIns);
      }
    },
    unRegisterPortlet(portletIns) {
      _.remove(this.portletWidgetInstanceList, portletIns);
    },
    loadComponent() {
      console.time('CD5:FasGeneratePortal:loadComponent');
      // return loadPortal('demo', ['TButton', 'TCard']);
    },
    checkInParamsIsBind: CheckInParamsIsBind,
    componentEdit(data) {
      this.showEditDialog(data.widget);
    },
    componentDelete(data) {
      this.removeItem(data.InstanceCode);
    },
    refreshWidgetByCode(InstanceCode) {
      if (Widget[InstanceCode]) {
        Widget[InstanceCode].Refresh();
      }
    },
    async getIsMaster() {
      let sgUrl = window.FrameSGHost + 'FASR-AuthUser&fasdevappid=fascommon';
      return new Promise((resolve, reject) => {
        window.getDataAsync(
          sgUrl,
          'post',
          {
            filter: JSON.stringify({
              BusinessType: 1,
              SubSystemCode: this.curInstance.SubSystemCode,
            }),
          },
          result => {
            if (result.data == true) {
              this.isMaster = true;
            }
            resolve();
          },
        );
      });
    },
    getPortletsCompDependency(ids) {
      let sgUrl =
        window.FrameSGHost +
        'FASR-GetPortletsCompDependency&fasdevappid=fascommon';
      return new Promise((resolve, reject) => {
        window.getDataAsync(
          sgUrl,
          'post',
          {
            ids: JSON.stringify(ids ? ids : []),
          },
          result => {
            window.PortletsCompDependency = result.data ? result.data : {};
            resolve(result.data);
          },
          error => {
            reject(error);
          },
        );
      });
    },
    deletePersonPortal() {
      let persionInstanceList = this.curInstanceList.filter(
        item => item.InstanceType == 2,
      );
      if (persionInstanceList.length == 0) {
        Funcs.Notify(
          Terms.message.warn,
          Terms.message.noPersonSetting,
          'warning',
        );
        return;
      }
      Funcs.Confirm(
        Terms.message.confirm,
        Terms.message.confirmDelCurMessage,
        () => {
          let sgUrl =
            window.FrameSGHost +
            'FASR-DeletePortalInstances&fasdevappid=' +
            window.getFasDevAppId();

          window.getDataAsync(
            sgUrl,
            'post',
            { portalIds: JSON.stringify([persionInstanceList[0].ID]) },
            result => {
              Funcs.Notify(
                Terms.message.notify,
                Terms.message.delSuccess,
                'success',
              );
              window.setTimeout(() => {
                let customList = this.curInstanceList.filter(
                  item => item.InstanceType == 2,
                );
                let personList = this.curInstanceList.filter(
                  item => item.InstanceType == 1,
                );
                this.$emit('reloadPortal', {
                  clear: !(customList.length && personList.length),
                });
              }, 500);
            },
          );
        },
        '',
        true,
        {},
      );
    },
    deleteCurrentPortal() {
      let InstanceType = this.curInstance.InstanceType;
      if (InstanceType == 0) {
        Funcs.Notify(
          Terms.message.confirm,
          Terms.message.cantDelDefault,
          'warning',
        );
        return;
      }
      let persionInstanceList = this.curInstanceList.filter(
        item => item.InstanceType == 1,
      );
      // let persionInstanceList = this.curInstanceList.filter(
      //   item => item.InstanceType == InstanceType,
      // );
      // if (persionInstanceList.length == 0) {
      //   Funcs.Notify(
      //     Terms.message.confirm,
      //     Terms.message.getCurInsError,
      //     'warning',
      //   );
      //   return;
      // }
      Funcs.Confirm(
        Terms.message.notify,
        Terms.message.confirmDelCurMessage,
        () => {
          let sgUrl =
            window.FrameSGHost +
            'FASR-DeletePortalInstances&fasdevappid=' +
            window.getFasDevAppId();
          window.getDataAsync(
            sgUrl,
            'post',
            { portalIds: JSON.stringify([persionInstanceList[0].ID]) },
            result => {
              Funcs.Notify(
                Terms.message.confirm,
                Terms.message.delSuccess,
                'success',
              );
              window.setTimeout(() => {
                this.$emit('reloadPortal', {
                  clear: true,
                });
              }, 500);
            },
          );
        },
        '',
        true,
        {},
      );
    },
    getLayoutInfoByResp() {
      let layoutInfo =
        this.curInstance.LayOutInfos &&
        this.curInstance.LayOutInfos[0]?.LayOutInfo
          ? JSON.parse(this.curInstance.LayOutInfos[0].LayOutInfo)
          : [];

      if (this.curInstance.LayoutInfoResponsive) {
        try {
          layoutInfo = JSON.parse(
            this.curInstance.LayoutInfoResponsive[this.colKey].LayOutInfo,
          );
        } catch (error) {}
      }
      return layoutInfo;
    },
    setCurInstance(curInstance) {
      this.isChanging = true;
      this.isFirst = true;
      this.visibleItems = [];
      this.curInstanceSelectChange('', curInstance);
      this.currenctPortalInstance = _.cloneDeep(curInstance);
      setTimeout(() => {
        this.isChanging = false;
      }, 300);
    },
    async curInstanceSelectChange(val, curInstance) {
      this.isChangeType = true;
      this.curInstance = this.curInstanceList.filter(item => item.ID == val)[0];
      if (curInstance) {
        this.curInstance = _.cloneDeep(curInstance);
       this.visibleItems = [];
      }
      if (
        this.curInstance.LayOutInfos &&
        this.curInstance.LayOutInfos.length > 0
      ) {
        this.element.options.layout = this.getLayoutInfoByResp();
      } else {
        this.element.options.layout = [];
      }
      if (
        this.curInstance.PortletInstances &&
        this.curInstance.PortletInstances.length > 0
      ) {
        this.element.list = this.curInstance.PortletInstances;
      } else {
        this.element.list = [];
      }

      //设计时数据
      this.layoutData = this.element.options.layout;
      this.getLayoutInfo(
        this.curInstance,
        this.enablePlan ? this.curInstance : '',
      ).then(() => {
        this.element.list = this.element.list.filter(item =>
          this.element.options.layout.some(
            items => items.i == item.InstanceCode || items.i == item.Code,
          ),
        );
        this.curInstanceID = this.curInstance.ID;
        this.$forceUpdate();
        this.layoutChanged = false;
        this.isLock = true;
        if (curInstance) {

          setTimeout(() => {
            this.handleScroll();
          }, 50);
        }
      });
    },
    async getLayoutInfo(curInstance, currenctPortalInstance) {
      this.portletInstancesLoadedCount = 0; //小部件加载计数
      if (!this.enablePlan) {
        if (
          !window.portalInstanceGroup ||
          window.portalInstanceGroup.length == 0
        )
          return Funcs.HandleError(Terms.message.noPortalWarnMessage);
        if (!window.portalInstanceGroup[this.InstanceCode])
          return Funcs.HandleError(Terms.message.noPortalWarnMessage);
      }

      let curInstanceList =
        (window.portalInstanceGroup &&
          _.cloneDeep(window.portalInstanceGroup[this.InstanceCode])) ||
        [];
      this.curInstanceList = _.orderBy(
        curInstanceList,
        ['InstanceType'],
        ['desc'],
      );
      //调试阶段只加载 系统方案
      if (!window.TQuasarBase) {
        this.curInstanceList = this.curInstanceList.filter(
          item => item.InstanceType == 0,
        );
      }
      this.curInstance = curInstance
        ? _.cloneDeep(this.curInstanceList).filter(
            item => item.ID == curInstance.ID,
          )[0]
        : this.curInstanceList[0];
      if (currenctPortalInstance) {
        this.curInstance = _.cloneDeep(currenctPortalInstance);
      }
      await this.getIsMaster();
      let _layout = [];
      if (
        this.curInstance.LayOutInfos &&
        this.curInstance.LayOutInfos.length > 0
      ) {
        _layout = this.getLayoutInfoByResp();
        // _layout.forEach(item => {
        //   item.zIndex = 1;
        //   item.ShowLoading = true;
        //   setTimeout(() => {
        //     item.ShowLoading = false;
        //   }, 1000);
        // });
        // if (this.$refs.portalGridLayout) {
        //   _layout = this.$refs.portalGridLayout.getResponsiveGridLayout(
        //   _layout,
        //   [],
        // );
        // };
        //   _layout.forEach((item=>{
        //   let position = this.getPosition(item.w,item.h,_layout)
        //   item = Object.assign(item,position)
        // }))
        // this.lastLayoutData = this.layoutData = _layout
        this.element.options.layout =
          this.lastLayoutData =
          this.layoutData =
            _layout;
      } else {
        this.element.options.layout = [];
      }
      let promiseList = [];
      if (!this.curInstance.PortletInstances)
        this.curInstance.PortletInstances = [];
      let ids = this.curInstance.PortletInstances.map(
        item => item.PortletMetadataID,
      );
      ids = ids.filter(
        item =>
          !window.PortletsCompDependency ||
          (window.PortletsCompDependency &&
            !window.PortletsCompDependency.hasOwnProperty(item)),
      );
      if (ids && ids.length > 0) {
        //动态获取依赖，只处理老数据，如果是新增则不在重复check
        try {
          await this.getPortletsCompDependency(ids);
        } catch (error) {}
      }
      if (
        this.curInstance.PortletInstances &&
        this.curInstance.PortletInstances.length > 0
      ) {
        // debugger;
        let eventList = [];
        this.curInstance.PortletInstances.forEach(ins => {
          // ins.ShowLoading = true;
          eventList.push(ins);
          //构建依赖关系
          this.generateParams(ins.Params, ins.Code, ins);
          //let Code = ins.Ext1;
          // if (!Code) {
          //   Code = ins.Name;
          // }
          // ins.Ext1 = '';
          // promiseList.push(
          //   new Promise(resolve => {

          //   }),
          // );
        });

        if (window[this.curInstance.Code]) {
          eventList.forEach(ie => {
            ie.Events = window[this.curInstance.Code][ie.InstanceCode]
              ? window[this.curInstance.Code][ie.InstanceCode]['Events']
              : [];
          });
        }

        this.element.list = eventList;
        this.generateRelation();
        //设置一下基础属性
        this.element.list = this.element.list.filter(item =>
          this.element.options.layout.some(items => items.i == item.Code),
        );

        this.curInstanceID = this.curInstance.ID;

        this.$nextTick(() => {
          this.isChangeType = false;
          //  this.handleScroll()
        });
        setTimeout(() => {
          promiseList = this.handleScroll(null,!this.enablePlan);
          Promise.all(promiseList).then(() => {
            if(!this.currenctPortalInstance.ID) return;
            this.$emit('complete');
          });
        }, 10);
      } else {
        //设置一下基础属性
        this.element.list = this.element.list.filter(item =>
          this.element.options.layout.some(
            items => items.i == item.InstanceCode,
          ),
        );
        this.curInstanceID = this.curInstance.ID;
        if(!this.currenctPortalInstance.ID) return;
        this.$emit('complete');
      }
    },
    formatData(list, isUpdate, PortalInstanceID) {
      let retList = [];
      list.forEach(item => {
        // let PortletMetadataID = item.PageMetaDataID; //item.options.portletMetaDataID;
        // let PortalInstanceID = item.PortalInstanceID;
        // if (!PortletMetadataID) {
        //   this.curInstanceList.forEach(ins => {
        //     if (ins.PortletInstances) {
        //       let result = ins.PortletInstances.filter(
        //         _item => _item.Code == item.Code,
        //       );
        //       if (result && result.length > 0) {
        //         PortletMetadataID = result[0].PortletMetadataID;
        //         PortalInstanceI = result[0].PortalInstanceID;
        //         return false;
        //       } else {
        //         PortletMetadataID = item.ID;
        //         PortalInstanceID = item.ID;
        //       }
        //     }
        //   });

        //   //PortletMetadataID = this.curInstanceList.filter(item=>item.Code == item.InstanceCode)[0].PortletMetadataID
        // }
        item.inParams = _.cloneDeep(item.Params);
        item.inParams &&
          item.inParams.forEach(param => {
            param.PortletInstanceID = item.ID;
            param.ID = '';
            //isExpression会变化，需要重新校验
            let isExpression =
              param.Value &&
              typeof param.Value === 'string' &&
              param.Value.indexOf('.') != -1 &&
              param.Value.indexOf('_generateCode_outParams_') == -1 &&
              param.Value.indexOf('LocalVars.') != 0;
            if (isExpression) {
              param.ParamValue = param.Value;
              if (param.DisplayHelpSetting) {
                param.DefaultValue =
                  typeof param.DefaultValue === 'object'
                    ? JSON.stringify(param.DefaultValue)
                    : param.DefaultValue;
              }
            } else {
              //帮助的就默认json

              param.ParamValue = param.Value || param.ParamValue;

              //param.ParamValue = param.DisplayHelpSetting?JSON.stringify(param.Value):param.Value
            }
          });
        item.inParams &&
          item.inParams.forEach(param => {
            delete param['isExpression'];
          });

        let obj = {
          ID: '',
          Code: item.InstanceCode || item.Code,
          Name: item.Name || '门户部件',
          PortletMetadataID: item.PortletMetadataID||item.ID,
          PortalInstanceID: PortalInstanceID,
          Title: item.Title,
          IsAutoRefresh: item.IsAutoRefresh,
          RefreshInterval: item.RefreshInterval,
          IsShowRefreshButton: item.IsShowRefreshButton,
          IsShowToolsbar: item.IsShowToolsbar,
          Params: item.inParams,
          SubSystemCode: item.subSystemCode,
          PageMetaDataID: item.PageMetaDataID||item.MetaDataID,
          toolsbarHeight: item.toolsbarHeight,
          toolsbarBackgroundColor: item.toolsbarBackgroundColor,
          isShowTitle: item.isShowTitle,
          Ext1: item.Ext1,
          Ext2: item.Ext2,
          PortletBusinessType:item.PortletBusinessType
        };
        retList.push(obj);
      });
      return retList;
    },
    rejestorCallBack() {
      window.saveAsCallback = this.saveByPlan;
    },
    savePortalPlanContent(isSave) {
      this.AdvanceQueryComponent.savePortalPlanContent(this.saveByPlan, {
        isSave: isSave,
      });
    },
    async saveLayoutChanged() {
      if (this.enablePlan) {
        return this.AdvanceQueryComponent.savePortalPlanContent(
          this.saveByPlan,
        );
      }
      //客户定制
      if (this.isMaster) {
        let customList = this.curInstanceList.filter(
          item => item.InstanceType == 1,
        );
        let persionInstanceList = this.curInstanceList.filter(
          item => item.InstanceType == 2,
        );
        //如果没有客户定制，始终提示一嘴
        if (
          this.curInstance.InstanceType == 0 &&
          !customList.length &&
          !persionInstanceList.length
          // (customList.length == 0 &&persionInstanceList.length==0)
        ) {
          return Funcs.Confirm(
            Terms.message.confirm,
            Terms.message.saveInstance,
            () => {
              return this._saveLayoutChanged(1);
            },
            () => {},
            true,
            {
              confirmButtonText: Terms.portalType.system,
              cancelButtonText: Terms.portalType.person,
              handleCancel: () => {
                return this._saveLayoutChanged(2);
              },
            },
          );
        } else {
          //走正常更新
          let InstanceType;
          if (this.curInstance.InstanceType == 0) {
            if (customList.length == 0) {
              InstanceType = 1;
            } else if (persionInstanceList.length == 0) {
              InstanceType = 2;
            }
          } else {
            InstanceType = this.curInstance.InstanceType;
          }

          return this._saveLayoutChanged(InstanceType);
        }
      } else {
        return this._saveLayoutChanged(2);
      }
    },
    async _saveLayoutChanged(instanceType, noRefrsh) {
      if (this.enablePlan) {
        return this.AdvanceQueryComponent.savePortalPlanContent(
          this.saveByPlan,
        );
      }
      //  Funcs.ShowLoading()
      let that = this;
      that.loading = true;
      let sgUrl =
        window.FrameSGHost +
        'FASR-CreateOrUpdatePortalInstance&fasdevappid=' +
        window.getFasDevAppId();
      try {
        let instanceObject = null;
        let persionInstanceList = this.curInstanceList.filter(
          item => item.InstanceType == 2,
        );
        //组织级别，暂时无使用
        let customList = this.curInstanceList.filter(
          item => item.InstanceType == 1,
        );

        //不是个人定制,新增
        if (
          instanceType == 0 ||
          (instanceType == 2 && persionInstanceList.length == 0) ||
          (instanceType == 1 && customList.length == 0)
        ) {
          let systemInstance =
            this.curInstanceList.filter(item => item.InstanceType == 0)[0] ||
            {};
          instanceObject = JSON.parse(JSON.stringify(systemInstance));
          instanceObject.ID = '';
          instanceObject.InstanceType = instanceType;
          delete instanceObject.LayOutInfos;
          // instanceObject.LayOutInfos = [
          //   {
          //     LayOutInfo: JSON.stringify(this.element.options.layout),
          //   },
          // ];
          instanceObject.LayoutInfoResponsive =
            this.curInstance.LayoutInfoResponsive;

          instanceObject.PortletInstances = this.formatData(this.element.list);
        } else {
          instanceObject =
            instanceType == 2 ? persionInstanceList[0] : customList[0];
          delete instanceObject.LayOutInfos;
          // instanceObject.LayOutInfos = [
          //   {
          //     LayOutInfo: JSON.stringify(this.element.options.layout),
          //   },
          // ];
          instanceObject.LayoutInfoResponsive =
            this.curInstance.LayoutInfoResponsive;
          instanceObject.PortletInstances = this.formatData(
            this.element.list,
            true,
          );
        }
        let SubscribeInfos = {};
        this.curInstanceList.forEach(item => {
          SubscribeInfos[item.InstanceCode] =
            item.options && item.options.relation ? item.options.relation : [];
        });
        instanceObject.SubscribeInfos = [
          {
            ID: '',
            Code: '34d053e3-3c3f-4f11-89e6-d19f8e5d5f52',
            Name: 'Sample Name',
            Description: 'Sample Description',
            PortalInstanceID: '',
            SourcePortletInstanceID: '',
            SourcePortletInstanceEventID: '',
            SubscribeOrder: 85,
            SubscribePortletInstanceID: ',',
            SubscribeActionDescription: '',
            SubscribeActionContent: JSON.stringify(SubscribeInfos),
          },
        ];

        window
          .getDataAsync(
            sgUrl,
            'post',
            { instance: JSON.stringify(instanceObject) },
            result => {
              Funcs.Notify(
                Terms.message.notify,
                Terms.message.saveSuccess,
                'success',
              );
              this.$emit('reloadPortal', {
                clear: instanceType == 2 || this.curInstance.InstanceType == 0,
              });
            },
          )
          .always(() => {
            this.layoutChanged = false;
            window.setTimeout(() => {
              this.$emit('reloadPortal', {
                clear: instanceType == 2 || this.curInstance.InstanceType == 0,
              });
            }, 500);
          });
      } catch (e) {
        this.layoutChanged = false;
      }
    },
    async saveByPlan(id) {
      let instanceObject = this.curInstance;
      instanceObject.PortletInstances = this.formatData(
        this.element.list,
        true,
      );
      if (id) {
        instanceObject.ID = id;
      }
      instanceObject.InstanceType = 2;
      let sgUrl =
        window.FrameSGHost +
        'FASR-CreateOrUpdatePortalInstance&fasdevappid=' +
        window.getFasDevAppId();
      return new Promise((resolve, reject) => {
        window
          .getDataAsync(
            sgUrl,
            'post',
            { instance: JSON.stringify(instanceObject) },
            result => {
              resolve(result);
              this.currenctPortalInstance = _.cloneDeep(this.curInstance);
            },
          )
          .always(() => {
            resolve('');
          });
      });
    },
    getGuid() {
      function t() {
        return ((65536 * (1 + Math.random())) | 0).toString(16).substring(1);
      }
      return (
        t() + t() + '-' + t() + '-' + t() + '-' + t() + '-' + t() + t() + t()
      );
    },
    generateOutParams(portalParamsInstance, instanceCode) {
      let callBackFnList = {};
      if (portalParamsInstance && portalParamsInstance.outParams) {
        for (let i in portalParamsInstance.outParams) {
          callBackFnList[`update:${i}`] = val => {
            portalParamsInstance.VBind[i] = val;
            //r如果还有依赖 更新依赖
            if (this.notifyInparamsList[instanceCode]) {
              this.notifyInparamsList[instanceCode].forEach(item => {
                if (item.outParamsCode == i) {
                  item.fn(val);
                }
              });
            }
          };
        }
      }
      if (this.eventList && this.eventList[instanceCode]) {
        this.eventList[instanceCode].forEach(el => {
          callBackFnList[el] = val => {
            try {
              this.$emit('Event_Filter', {
                portalCode: instanceCode,
                instanceCode: this.InstanceCode,
                data: val,
                eventName: el,
              });
              // this.$parent.$parent[`${this.InstanceCode}_OnEvent_Filter`](val)
            } catch (error) {}
          };
        });
      }

      portalParamsInstance.VOn = callBackFnList;
    },
    generateRelation() {
      for (let i in this.portalParamsInstance) {
        this.generateOutParams(this.portalParamsInstance[i], i);
      }
    },
    generateParams(params, code, target) {
      if (!params) return;
      params.forEach(item => {
        if (!item.ParamType) {
          item.ParamType = item.VariableType;
          item.ParamValue = '';
        }
      });
      if (!window.portalParamsInstance) {
        window.portalParamsInstance = {};
        window.portalParamsInstance[this.InstanceCode] = {};
      }
      let outParams = params.filter(item => item.ParamType == 2);
      let inParams = params.filter(item => item.ParamType == 1);
      outParams.forEach(item => {
        if (!this.outParams[code]) this.outParams[code] = {};
        if (!this.outParams[code][item.Code])
          this.outParams[code][item.Code] = {};
        this.outParams[code][item.Code] = item.ParamValue || item.DefaultValue;
      });
      inParams.forEach(item => {
        //注销监听器
        if (!this.inParams[code]) this.inParams[code] = {};
        if (!this.inParams[code][item.Code])
          this.inParams[code][item.Code] = {};
        item.ParamValue = item.ParamValue || item.DefaultValue || '';
        if (item.PublicParamsSetting) {
          let PublicParamsSetting = JSON.parse(item.PublicParamsSetting);
          item.ParamValue = `LocalVars.PublicParams.${PublicParamsSetting.Code}`;
        }
        if (item.ParamValue.indexOf('_generateCode_outParams_') != -1) {
          this.inParams[code][item.Code] = item.DefaultValue;
        } else if (item.ParamValue.indexOf('LocalVars.') == 0) {
          if (item.ParamValue.indexOf('LocalVars.PublicParams') == 0) {
            if (!window.LocalVars.PublicParams) {
              window.LocalVars.PublicParams = {};
            }
            //_.set(window.LocalVars, item.ParamValue.replace('LocalVars.', ''), '')
          }
          let localVarsKey = item.ParamValue.replace('LocalVars.', '');
          this.inParams[code][item.Code] = _.get(window, item.ParamValue);
          if (!this.localVarsWatcher[`${localVarsKey}`]) {
            this.localVarsWatcher[`${localVarsKey}`] = [];
          }
          this.localVarsWatcher[`${localVarsKey}`].push({
            key: localVarsKey,
            value: _.get(this.localvars, localVarsKey),
            instanceCode: code,
            code: item.Code,
          });
        } else {
          this.inParams[code][item.Code] = item.ParamValue || item.DefaultValue;
          if (
            [
              'MetricsConfig',
              'StaticMetricsFilters',
              'MetricsFilters',
            ].includes(item.Code)
          ) {
            try {
              this.inParams[code][item.Code] = eval(
                item.ParamValue || item.DefaultValue,
              );
            } catch (error) {}
          }
        }
      });
      window.portalParamsInstance[this.InstanceCode][code] =
        this.portalParamsInstance[code] = {
          detail: {
            outParams: outParams,
            inParams: inParams,
          },
          ins: target,
          target: null,
          outParams: this.outParams[code],
          inParams: this.inParams[code],
          subInfo: {},
          VBind: Object.assign({}, this.inParams[code], this.outParams[code]),
          VOn: {},
          refreshFn: () => {
            this.refreshPortal(code);
          },
        };
      inParams.forEach(item => {
        // if (
        //   item.ParamValue.indexOf('_generateCode_outParams_') != -1 ||
        //   item.ParamValue.indexOf('LocalVars.') == 0
        // ) {
        this.updateInparams(code, item.Code, item.ParamValue);
        // }
      });

      // 定时刷新
      if (target.IsAutoRefresh) {
        if (this.autoRefreshList[code]) {
          window.clearInterval(this.autoRefreshList[code]);
          this.autoRefreshList[code] = null;
        }
        this.autoRefreshList[code] = window.setInterval(
          this.portalParamsInstance[code].refreshFn,
          target.RefreshInterval * 1000,
        );
      }
    },
    updatePortletSureData(data) {
      if (data.updateInparamsList && data.updateInparamsList.length > 0) {
        data.updateInparamsList.forEach(i => {
          //if (i.value.indexOf('_generateCode_outParams_') != -1) {
          this.updateInparams(i.instanceCode, i.code, i.value);
          //}
        });
      }
      if (data.portalInstance) {
        let instanceCode = data.portalInstance.InstanceCode;
        //自动刷新
        if (
          this.portalParamsInstance[instanceCode].ins.IsAutoRefresh !=
            data.portalInstance.IsAutoRefresh ||
          this.portalParamsInstance[instanceCode].ins.RefreshInterval !=
            data.portalInstance.RefreshInterval
        ) {
          if (this.autoRefreshList[instanceCode]) {
            window.clearInterval(this.autoRefreshList[instanceCode]);
            this.autoRefreshList[instanceCode] = null;
          }
          if (data.portalInstance.IsAutoRefresh) {
            this.autoRefreshList[instanceCode] = window.setInterval(
              this.portalParamsInstance[instanceCode].refreshFn,
              data.portalInstance.RefreshInterval * 1000,
            );
          }
        }
        if (
          this.portalParamsInstance[instanceCode].ins.Title !=
            data.portalInstance.Title ||
          this.portalParamsInstance[instanceCode].ins.IsShowRefreshButton !=
            data.portalInstance.IsShowRefreshButton ||
          this.portalParamsInstance[instanceCode].ins.IsAutoRefresh !=
            data.portalInstance.IsAutoRefresh ||
          this.portalParamsInstance[instanceCode].ins.RefreshInterval !=
            data.portalInstance.RefreshInterval
        ) {
          this.emitChange();
        }
        this.portalParamsInstance[instanceCode].ins.Title =
          data.portalInstance.Title;
        this.portalParamsInstance[instanceCode].ins.IsShowRefreshButton =
          data.portalInstance.IsShowRefreshButton;
        this.portalParamsInstance[instanceCode].ins.IsAutoRefresh =
          data.portalInstance.IsAutoRefresh;
        this.portalParamsInstance[instanceCode].ins.RefreshInterval =
          data.portalInstance.RefreshInterval;
      }
    },
    async addPortletSureData(row) {
      row = _.cloneDeep(row);
      row.data.forEach(item => {
        item.Ext2 = item.RelatedUrl;
        let Code = item.Ext1 || item.Code || item.Name;
        if (!item.Ext1) {
          item.Ext1 = '';
        }

        item.Ext3 =
          item.PorletPageSize ||
          JSON.stringify({
            width: 2,
            height: 2,
          });
        item.Params = _.cloneDeep(item.Variables);
        item.Title = item.Title || item.Name;

        item.Code = 'fas_portlet' + this.getGuid().substring(0, 6);
        //构建依赖关系
        this.generateParams(item.Params, item.Code, item);
        //异步加载
        item.ShowLoading = true;
        let layout = this.element.options.layout;
        let _x = 2;
        let _y = 2;
        let PorletPageSize = JSON.parse(item.Ext3);
        if (PorletPageSize) {
          _x = parseInt(PorletPageSize.width);
          _y = parseInt(PorletPageSize.height);
        }
        //获取左上角 右下角
        let position = this.getPosition(
          _x,
          _y,
          this.layoutData,
          this.rowsNum || 24,
        );
        layout.push({
          // x: (layout.length * 2) % (this.colNum || 24),
          ...position,
          w: _x,
          h: _y,
          i: item.Code,
          PortletRelatedComponents: item.PortletRelatedComponents,
          minCellCount: item.MinCellCount || 1,
        });
        this.element.options.layout = this.layoutData = layout;
        /**
         * 其余档位的数据信息存储
         */
        if (this.curInstance.LayoutInfoResponsive) {
          let breakpoint = { lg: 24, md: 16, sm: 12, xs: 10, xxs: 4 };
          // try {
          //   layoutInfo = JSON.parse(this.curInstance.LayoutInfoResponsive[this.colKey].LayOutInfo)
          // } catch (error) {

          // }
          for (let i in this.curInstance.LayoutInfoResponsive) {
            if (!this.curInstance.LayoutInfoResponsive[i]) {
              this.curInstance.LayoutInfoResponsive[i] = {
                LayOutInfo: JSON.stringify([]),
              };
            }
            let __layout = JSON.parse(
              this.curInstance.LayoutInfoResponsive[i].LayOutInfo,
            );
            let position = this.getPosition(_x, _y, __layout, breakpoint[i]);
            __layout.push({
              // x: (layout.length * 2) % (this.colNum || 24),
              ...position,
              w: _x,
              h: _y,
              i: item.Code,
              PortletRelatedComponents: item.PortletRelatedComponents,
              minCellCount: item.MinCellCount || 1,
            });
            this.curInstance.LayoutInfoResponsive[i].LayOutInfo =
              JSON.stringify(__layout);
          }
        }
        item.InstanceCode = item.Code;
        this.layoutChanged == true;
        if (!this.element.list) {
          this.element.list = [];
        }

        let portalList = [];
        if (item.PortletRelatedComponents) {
          portalList = item.PortletRelatedComponents.split(',');
        }
        item.LoadJsComponent = true;
        this.element.list.push(item);
        loadPortal(item.Ext2, Code, portalList).then(res => {
          item.Ext1 = Code;
          item.ShowLoading = true;

          setTimeout(() => {
            this.element.list.forEach(items => {
              if (items.Code == item.InstanceCode) {
                items.Ext1 = Code;
                // setTimeout(() => {
                //   items.ShowLoading = false;
                // }, 1500);

                items.LoadJsComponent = false;
                this.visibleItems.push(items.Code);
              }
            });
          }, 0);
        });
      });
      this.generateRelation();
      if (row.data.length > 0) {
        this.emitChange();
      }
    },

    getPosition(width, height, layoutData, rowsNum) {
      //计算所有数据
      let layout = _.cloneDeep(layoutData);
      //按照点位排序
      let start = null,
        end = 0;
      layout.forEach(item => {
        if (!start && start !== 0) {
          start = item.x;
        }
        if (start > item.x) {
          start = item.x;
        } else {
        }
        if (end < item.y + item.h) {
          end = item.y + item.h;
        }
      });
      // 如果左侧区域够直接填充
      if (width < start) {
        return {
          x: 0,
          y: end,
        };
      }
      let stop = false;
      let loop = 0;
      while (!stop) {
        if (end <= loop) stop = true;
        for (let i = 0; i < rowsNum; i++) {
          if (
            !layout.some(item => {
              /**
               * 根据元素的宽高 计算，当前位置存在重合继续下一步
               *
               * 重合判断依据：
               *    根据当前元素的四个点位 x,y&&x+w,y&&x,y+h&&x+w,y+h
               *    如果当前位置与需要加入的元素存在重叠则继续直到找到符合条件的，如果一直不存在，则在最左侧底部追加
               */

              return (
                ((i + width > item.x && i + width < item.x + item.w) ||
                  (i >= item.x && i < item.x + item.w) ||
                  i + width > rowsNum) &&
                ((height + loop > item.y && height + loop < item.y + item.h) ||
                  (loop >= item.y && loop < item.y + item.h))
              );
            })
          ) {
            stop = true;
            return {
              x: i,
              y: loop,
            };
          }
        }
        loop++;
      }
      return {
        x: 0,
        y: loop, // puts it at the bottom
      };
    },
    handleSelectPortlet(item) {},
    resetPosition() {
      let __layout = [];
      this.layoutData.forEach(item => {
        let position = this.getPosition(item.w, item.h, __layout, this.rowsNum);
        __layout.push({
          ...position,
          w: item.w,
          h: item.h,
          i: item.i,
          PortletRelatedComponents: item.PortletRelatedComponents,
          minCellCount: item.minCellCount || 1,
          isReComputedPosition: item.isReComputedPosition,
          minHeight: item.minHeight,
        });
      });
      this.layoutData = __layout;
    },
    portalLoaded(item, curElement, isreload) {
      if (this.$refs[item.i] && this.$refs[item.i][0]) {
        Widget[item.i] = this.$refs[item.i][0];
      } else {
        if (isreload && isreload < 6) {
          return;
        }
        if (!isreload) {
          isreload = 0;
        }
        isreload++;
        setTimeout(() => {
          this.portalLoaded(item, curElement, isreload);
        }, 50);
      }
      if (this.colKey == 'xxs' && !item.isReComputedPosition) {
        setTimeout(() => {
          curElement.ShowLoading = false;
        }, 50);
        // let isLock  =  this.isLock
        // 选择目标节点
        const targetNode = this.$refs[item.i][0].$el;
        if (!targetNode) {
          item.isReComputedPosition = true;
          curElement.ShowLoading = false;
          return;
        }

        // 创建一个观察者对象
        const observer = new MutationObserver((mutationsList, observer) => {
          // this.isLock=!this.isLock
          if (!this.$refs[item.i] || !this.$refs[item.i][0]) return;
          if (this.$refs[item.i][0].$el.offsetHeight) {
            if (
              item.h ==
              Math.ceil(
                this.$refs[item.i][0].$el.offsetHeight /
                  (30 + this.portalPadding * 1 - 2),
              )
            ) {
              item.isReComputedPosition = true;
              curElement.ShowLoading = false;
              return;
            }
            if (!item.minHeight) {
              item.minHeight = item.h;
            }
            if (
              item.minHeight <
              Math.ceil(
                this.$refs[item.i][0].$el.offsetHeight /
                  (30 + this.portalPadding * 1 - 2),
              )
            ) {
              item.h = Math.ceil(
                this.$refs[item.i][0].$el.offsetHeight /
                  (30 + this.portalPadding * 1 - 2),
              );
            }
            for (let i in this.layoutData) {
              if (this.layoutData[i].i == item.i) {
                this.layoutData[i] = item;
                this.curInstance.LayoutInfoResponsive['xxs'].LayOutInfo =
                  JSON.stringify(this.layoutData);
              }
            }
            // this.visibleItems = this.visibleItems.filter(ii=>ii!=item.i)
            item.isReComputedPosition = true;
            curElement.ShowLoading = false;
            this.$nextTick(() => {
              setTimeout(() => {
                this.isFirst = true;
                this.resetPosition();
              }, 50);
            });

            setTimeout(() => {
              // 以后，您可以停止观察
              observer.disconnect();
              curElement.ShowLoading = false;
            }, 10000);
          }

          this.$nextTick(() => {
            // this.isLock=isLock
          });
        });
        // 使用配置文件调用observe方法
        const config = { attributes: true, childList: true, subtree: true };
        // 传入目标节点和观察选项开始观察
        observer.observe(targetNode, config);
      } else {
        curElement.ShowLoading = false;
      }
    },
    lockChange(val) {
      this.isLock = val;
    },
    breakpointChangedEvent(newBreakpoint, newLayout) {
      this.rowsNum = { lg: 24, md: 16, sm: 12, xs: 10, xxs: 4 }[newBreakpoint];
      this.colKey = newBreakpoint;

      if (this.rowsNum == sessionStorage.rowsNum) return;

      sessionStorage.setItem('rowsNum', this.rowsNum);
      document.body.style.setProperty('--t-cols', this.rowsNum);
      this.layoutData = this.element.options.layout =
        this.getLayoutInfoByResp();

      if (this.colKey == 'xxs') {
        if (this.layoutData.some(item => !item.isReComputedPosition)) {
          this.visibleItems = [];
          this.handleScroll();
        }
      }
      this.isFirst = true;
    },
    handleLayoutListUpdated(layout) {
      //同步一下数据

      if (this.isFirst) {
        setTimeout(() => {
          this.isFirst = false;
        }, 100);

        return;
      }
      this.element.options.layout = layout;
      if (this.curInstance.LayoutInfoResponsive) {
        this.curInstance.LayoutInfoResponsive[this.colKey].LayOutInfo =
          JSON.stringify(layout);
      }
      this.emitChange();
    },
    removeItem: async function (val) {
      Funcs.Confirm(
        Terms.message.confirm,
        this.$q.lang.portal.deletePortalet,
        () => {
          const index = this.element.options.layout
            .map(item => item.i)
            .indexOf(val);
          this.element.options.layout.splice(index, 1);
          const index2 = this.element.list.map(item => item.Code).indexOf(val);

          this.element.list.splice(index2, 1);
          this.layoutData = this.layoutData.filter(item => item.i != val);
          if (this.curInstance.LayoutInfoResponsive) {
            for (let i in this.curInstance.LayoutInfoResponsive) {
              let __layout = JSON.parse(
                this.curInstance.LayoutInfoResponsive[i].LayOutInfo,
              );
              const index = __layout.map(item => item.i).indexOf(val);
              __layout.splice(index, 1);
              this.curInstance.LayoutInfoResponsive[i].LayOutInfo =
                JSON.stringify(__layout);
            }
          }
        },
        () => {},
        true,
        {},
      );
    },
    showEditDialog(data) {
      this.$emit('editData', {
        portalParamsInstance: _.cloneDeep(this.portalParamsInstance),
        currenctInstanceCode: data.Code,
        data: _.cloneDeep(data),
      });
      //this.$refs.RtEditorPortletHelper.open(data);
    },
    showAddDialog() {
      this.isLock = false;
      this.$refs.rtAddPortletHelper.open();
    },

    /**
     * changeKey:2023-04-21-PortletDesignEventHandler
     * 2023年4月21日 门户组件设计时小部件事件注册
     */
    snapshootPortletDesignEventHandler() {
      if (
        !this.portletDesignEventHandlerMapping &&
        _.size(this.element.list) > 0
      ) {
        this.portletDesignEventHandlerMapping = _.transform(
          this.element.list,
          (mapping, designPortlet) => {
            mapping[designPortlet.InstanceCode] = designPortlet.Events;
          },
          {},
        );
      }
    },
    restorePortletDesignEventHandlerByInstanceCode(portletIC) {
      // debugger;
      let portlet = this.portletDesignEventHandlerMapping[portletIC];
      if (portlet) {
        if (Widget[portletIC] && Widget[portletIC].widget) {
          let events = Widget[portletIC].widget.Events;
          _.each(portlet, mapItem => {
            // debugger;
            let runtimeEvent = _.find(events, evt => {
              return evt.Name == mapItem.Code || evt.Code == mapItem.Code;
            });
            if (!runtimeEvent) {
              events.push(mapItem);
            }
          });
        }
      }
    },
    restorePortletDesignEventHandlerALL() {
      // debugger;
      for (const portletIC in this.portletDesignEventHandlerMapping) {
        if (Widget[portletIC] && Widget[portletIC].widget) {
          let events = Widget[portletIC].widget.Events;
          _.each(this.portletDesignEventHandlerMapping[portletIC], mapItem => {
            // debugger;
            let runtimeEvent = _.find(events, evt => {
              return evt.Name == mapItem.Code || evt.Code == mapItem.Code;
            });
            if (!runtimeEvent) {
              events.push(mapItem);
            }
          });
        }
      }
    },
    restorePortletDesignEventHandler(portletIC) {
      if (portletIC) {
        this.restorePortletDesignEventHandlerByInstanceCode(portletIC);
      } else {
        this.restorePortletDesignEventHandlerALL();
      }
    },
    /** END 2023-04-21-PortletDesignEventHandler */
  },
  watch: {
    portalPadding: val => {
      document.body.style.setProperty('--t-size', `calc(100% - ${val / 2}px)`);
      document.body.style.setProperty('--t-portal-padding', `${val / 2}px`);
      document.body.style.setProperty(
        '--t-computed-height',
        `${30 + val * 1 - 2}px`,
      );
    },
    localvars: {
      deep: true,
      handler(val) {
        for (let item in this.localVarsWatcher) {
          let targetValue = _.get(this, `localvars.${item}`);
          this.localVarsWatcher[item].forEach(i => {
            let oldValue = i.value;
            let isNotEqual = targetValue != oldValue;
            try {
              isNotEqual =
                JSON.stringify(targetValue) != JSON.stringify(oldValue);
            } catch (error) {}
            if (isNotEqual) {
              i.value = _.cloneDeep(targetValue);
              this.portalParamsInstance[i.instanceCode].VBind[i.code] =
                _.cloneDeep(targetValue);
            }
          });
        }
      },
    },
    layoutData: {
      deep: true,
      immediate: true,
      handler(val) {
        _.set(window, 'LocalVars.PortalMetadata.layout', val);
      },
    },
    model: {
      deep: true,
      handler(val) {
        this.dataModels = val;
      },
    },
  },
};
</script>

